/**
 @project DeltaSet JavaScript Library
 @version 1.0.0
 @description This is needed by deltaset-faces.
 @author Dimitar Makariev
 */

/* 
 * common javascripts needed by deltaset-faces
 * @author Dimitar Makariev
 */


/**
 * @name deltaset
 * @namespace
 */

/*
 * Create top level namespace - deltaset
 */
var deltaset = deltaset || {};
deltaset.loadingLabel=deltaset.loadingLabel ||'loading';
deltaset.okLabel=deltaset.okLabel ||'Ok';
deltaset.cancelLabel=deltaset.cancelLabel ||'Cancel';
deltaset.confirmQuestionLabel=deltaset.confirmQuestionLabel||'Are you sure?';
deltaset.confirmTitleLabel=deltaset.confirmTitleLabel||'Confirm';


deltaset._dialogRepo=[];

deltaset.dialog = function(id){    
    if(null==deltaset._dialogRepo[id]){
        deltaset._dialogRepo[id]=new deltaset._dialog(id);
    }   
    return deltaset._dialogRepo[id];
}

deltaset.escapedId=function(someRealId){
    return someRealId.replace(/:/g,"\\:");
}

deltaset._dialog=function(id){
    this.id=id;
    this.realId=null;
    this.dialogDivObj=null;
    this.keepOpen=false;
    this.register=function(realId){        
        if(null!=this.realId){
            //alert('WARNING cannot register realId='+realId+' !\ndialog with id='+id+'\nalready registered with realId='+this.realId);                  
            //var debugStr="";
            var escapedId="#"+this.realId.replace(/:/g,"\\:"); //this fixes the jsf created ID to be used by jQuery
            //alert(escapedId)
            //alert(jQuery(escapedId).length)            
            //var removeAdditional=jQuery(escapedId).length>1;
            jQuery(escapedId).each(function(index){
               
                //debugStr+="index="+index+" id="+jQuery(this).attr("id")+"\n";  
                //debugStr+="parent="+jQuery(this).parent()[0].tagName+"\n";                
                //if("BODY"==jQuery(this).parent()[0].tagName){
                
                if(index>0){ //removeAdditional
                    //alert('try to remove '+this);
                    //this here is needed because of AJAX loading of the same dialog
                    //should be used with dialog('destroy')
                    jQuery(this).remove();
                }                           
            });            
            //alert("after remove="+jQuery(escapedId).length)
            //alert("\n\ndebugStr\n"+debugStr);
            this.dialogDivObj=document.getElementById(realId);
        }else{
            this.realId=realId;
            this.dialogDivObj=document.getElementById(realId);
        }
        return this;
    };   
    this.keep=function(flag){
        this.keepOpen=flag;
    };
    //returns true if closed; false if open
    this.keepOrClose=function(){
        
        if(false==this.keepOpen){
            this.close();
            return true;
        }
        return false;
    };
    this.beforeclose=function(fn){        
        jQuery(this.dialogDivObj).bind('dialogbeforeclose',fn);
        return this;
    }
    this.close=function(){
        //jQuery(this.dialogDivObj).dialog('close');
        //see this.register for comment why destroy is used and not close 
        jQuery(this.dialogDivObj).dialog('destroy');               
    };
    this.open=function(){  
        //alert("dialog.open is called screen.heigh="+$(window).height());
        jQuery(this.dialogDivObj).dialog({
            autoOpen: false,
            height: 'auto',
            width:'auto',
            modal: true,
            open: function(event, ui) {
                deltaset._innerUpdateRichTextIframesAfterOpen_Counter=0;
                setTimeout("deltaset._innerUpdateRichTextIframesAfterOpen()", 250);
                
//                jQuery('.ds-rich-text-editor-frame').each(function(){
//                    this.contentWindow.document.designMode =  "on" ;
//                    this.contentDocument.designMode = "on";
//                    
//                    var frameId = this.id
//                    var textareaId = frameId.replace(":iframe",":textarea");
//                    var textareaObj = document.getElementById(textareaId);
//                    this.contentWindow.document.body.innerHTML=textareaObj.value;
//                });
           },
            close: function() {
            //alert('dialog is going to be closed');
            //allFields.val('').removeClass('ui-state-error');
            }
        });
        jQuery(this.dialogDivObj).dialog('open');
        
    };
}

deltaset._innerUpdateRichTextIframesAfterOpen_Counter=0;
deltaset._innerUpdateRichTextIframesAfterOpen = function(){
    jQuery('.ds-rich-text-editor-frame').each(function(){
        this.contentWindow.document.designMode =  "On" ;
        this.contentDocument.designMode = "on";
                    
        var frameId = this.id
        var textareaId = frameId.replace(":iframe",":textarea");
        var textareaObj = document.getElementById(textareaId);
        try{
           if(deltaset._innerUpdateRichTextIframesAfterOpen_Counter<4
              && "on" !=this.contentDocument.designMode){
                 deltaset._innerUpdateRichTextIframesAfterOpen_Counter++;
                 setTimeout("deltaset._innerUpdateRichTextIframesAfterOpen()", 250); 
            } 
           this.contentWindow.document.body.innerHTML=textareaObj.value;
        }catch(e){
            if(deltaset._innerUpdateRichTextIframesAfterOpen_Counter<4){
                 deltaset._innerUpdateRichTextIframesAfterOpen_Counter++;
                 setTimeout("deltaset._innerUpdateRichTextIframesAfterOpen()", 250); 
            }
        }
    });
}

/**
 * confirm
 * TODO: add global config for the message (customizable through applyStyle.xhtml),
 * TODO: add 'local' customization:
 * deltaset.confirm(this).ask(text) ?
 * deltaset.confirm(this).text(text) ?
 * FIXME: change the buttons to pure html with style 'ds-button' or apply jQuery.button from script;
 * FIXME: localize button names..
 */
deltaset.confirm=function(target,confirmLabel) {    
    var confirmText= confirmLabel || deltaset.confirmQuestionLabel;
    //alert('dsConfirm :'+confirmText+'\ntarget='+target+'\ntarget.dsConfirmed='+target.dsConfirmed);
    var exclamationMarkSpan='<span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 0px 0;"></span>';
    //var buttonBar='<input type="button" value="Ok" class="ds-button">';
    this.flagButtonPressed=false;
    this.confirmResult=false;
    //alert(target.onclick)
    if(true==target.dsConfirmed){
        target.dsConfirmed=false;
        return true;
    }
    target.dsConfirmed=false;
    var $confirm = jQuery('<div></div>')
    .html(exclamationMarkSpan+confirmText)
    .dialog({
        autoOpen: false,
        resizable: false,
        modal: true,
        dialogClass:'ds-confirm',
        minHeight:'20',
        height: 'auto',
        width:200,
        title: deltaset.confirmTitleLabel,
        buttons: {
            'Ok':function(){
                //this.flagButtonPressed=true;
                //this.confirmResult = true;
                target.dsConfirmed=true;
                jQuery(this).dialog('close');
                //jQuery(target).onclick();
                //target.onclick();
                target.click();
            },
            'Cancel':function(){
                //this.flagButtonPressed=true;
                //this.confirmResult = false;
                target.dsConfirmed=false;
                jQuery(this).dialog('close');
            }
        }
    });
   
    var ama=$confirm.dialog( "option", "buttons" );

    eval("var newButtons={'"+deltaset.okLabel+"':function(){},'"+deltaset.cancelLabel+"':function(){}}");
    newButtons[deltaset.okLabel]=ama['Ok'];
    newButtons[deltaset.cancelLabel]=ama['Cancel'];
    $confirm.dialog( "option", "buttons", newButtons );


    $confirm.dialog('open');
 
    return false;
}

//////// date picker
deltaset.datePicker=function(objId,pattern,changeYearFlag,changeMonthFlag){
    var obj = document.getElementById(objId);
    //var dateFormatStr='dd/mm/yy';
    var dateFormatStr=deltaset._converJavaToJqueryDateFormat(pattern);//here should be a converter function
    jQuery(obj).datepicker({
        dateFormat: dateFormatStr,
        changeYear: changeYearFlag,
        changeMonth: changeMonthFlag
    });
}

/**
 * converter used by datePicker
 */
deltaset._converJavaToJqueryDateFormat=function(javaDateFormat) {
    // alert('javaDateFormat='+javaDateFormat)
    var result=javaDateFormat;
    result=deltaset._chain(result,[{
        match:'yyyy',
        replace:'yy'
    },{
        match:'yy',
        replace:'y'
    }]);
    result=deltaset._chain(result,[{
        match:'MMMM',
        replace:'MM'
    },{
        match:'MMM',
        replace:'M'
    },{
        match:'MM',
        replace:'mm'
    },{
        match:'M',
        replace:'m'
    }]);
    //result=deltaset._chain(result,[{match:'dd',replace:'dd'},{match:'d',replace:'d'}]);
    return result;
}

/**
 * used by datePicker
 */

deltaset._ifThen=function(ins,opt) {
    //alert('ifThen ins='+ins)
    if(-1!=ins.indexOf(opt.match)){
        return ins.replace(opt.match,opt.replace);
    }
    return ins;
}

/**
 * chain used by datePicker
 */
deltaset._chain=function(input,optArray) {
    for(i=0;i<optArray.length;i++){
        var result=deltaset._ifThen(input,optArray[i]);
        if(result!=input){
            return result;
        }
    }
    return input;
}


/**
 * display detail..
 * used in rowButtonsAjax.xhtml together with detail.xhtml
 * should be 'rare' choise
 * used only for the 'table->detail under' case.
 */
deltaset.displayDetail=function(data,detailId){
    if(0==detailId.indexOf(':')){
        detailId=detailId.substring(1);
    }
    var o=document.getElementById(detailId);
    if('begin'==data.status){
        jQuery(o).hide();
    }
    if('success'==data.status){
        jQuery(o).fadeIn('slow');
    }
}

/**
 * decorate ds grid - used in pagedTable.xhtml and pagedDataTable.xhtml
 */
deltaset.decorateDsGrid=function(tableId, options){

    if(0==tableId.indexOf(':')){
        tableId=tableId.substring(1);
    }

    var tableObj = document.getElementById(tableId);
    //if tableObj is null then the styling should not apply to anything
    if(null==tableObj){
        return;
    }

    var defaultOptions={
        highlight:true
    };


    //alert('tableObj='+tableObj);
    jQuery.extend(defaultOptions,options);

    jQuery('thead tr th',tableObj).addClass('ui-state-default');
    jQuery('tbody tr.ds-grid-row',tableObj).hover(
        function(){
            jQuery('td', this).addClass('ui-state-hover');
        },
        function(){
            jQuery('td', this).removeClass('ui-state-hover');
        }
        );
          //  .toggle(
       // function(){
            //alert('toggle 1 defaultOptions.highlight='+defaultOptions.highlight+'\ntableId='+tableId+'\nthis='+this);
            //the function is needed for 'selecting' visually a line from the table
            //TODO: with parentNode it is not working quite properly..
            //TODO: should change it to proper jQuery expression
       //     alert(jQuery(this).attr('class'))
            //sometimes triggers only the event from the image.. not the tr(td) click event
            //$('td', this.parentNode).removeClass('ui-state-highlight');
            //$('td', this).addClass('ui-state-highlight');
            //jQuery('td', this.parentNode).removeClass('ui-state-highlight');
           // if(true==defaultOptions.highlight){
                //$(element).is(":visible")
             //   jQuery(this).parent().children('tr').children('td').removeClass('ui-state-highlight');
               // jQuery(this).parent().children('tr.ds-grid-detail-row').not(this).hide();
                //jQuery(this).show();
                
                //jQuery('td', this).addClass('ui-state-highlight');
            //}
       // },
       // function(){
       //     alert('toggle 2'+'\ntableId='+tableId)
       //     jQuery('td', this).removeClass('ui-state-highlight');
       // }
       // );
    jQuery('tbody tr td',tableObj).not('.ds-grid-detail-row').addClass('ui-widget-content');
}
/**
 * opens a single detail row , closes all the others, almost like 'accordion'
 */
deltaset.accordionDetailRow=function(thisTr){
    jQuery(thisTr).parent().children('tr.ds-grid-detail-row').hide();
    jQuery(thisTr).parent().find('td').removeClass('ui-state-highlight');
    jQuery('td',thisTr).addClass('ui-state-highlight');
    jQuery(thisTr).next('tr.ds-grid-detail-row').show();
}


/**
 * detail row opener  
 */
deltaset.openDetailRow=function(event,currentRow,params) {
    var nextTr=jQuery(currentRow).next('tr');

    var ajaxRenderId=currentRow.id+':detail-row';
    var ajaxRenderObj = document.getElementById(ajaxRenderId);
    //alert(jQuery(ajaxRenderObj).html());
    //alert(ajaxRenderObj)
    if(nextTr.css('display')=='none'){
        var options = {
            render:ajaxRenderId,
            onevent: function(data){
                if('success'==data.status){
                    jQuery(ajaxRenderObj).unblock();
                }
            //var str='';
            // for (var i in data){
            // str+='data.'+i+'='+eval('data.'+i)+'\n';
            //}
            //alert('onevent: data=\n'+str);
            },
            onerror:function(data){

            //var str='';
            // for (var i in data){
            //     str+='data.'+i+'='+eval('data.'+i)+'\n';
            // }
            //alert('onerror data='+str);

            }
        };
        jQuery.extend(options,params);

        jsf.ajax.request(currentRow,event,options);
        jQuery(ajaxRenderObj).html('<div style="padding:30px;">'+deltaset.loadingLabel+'</div>');
        nextTr.toggle();
        /*jQuery.blockUI({
                message: '<h1>Processing</h1>',
                css: { border: '3px solid #a00' }
        });*/
        jQuery(ajaxRenderObj).block({
            message: null
        });
    }else{
        nextTr.toggle();
    }
}

//////////////
/**
 * decorateIfError
 */
deltaset.decorateIfError=function(componentId) {
    var messageObj = document.getElementById(componentId+':errorMessage');
    var inputObj = document.getElementById(componentId+':inputField');

    var hasError= ''!=messageObj.innerHTML;
    if(true==hasError){
        jQuery(inputObj).addClass('ui-state-highlight');
        jQuery(inputObj).removeClass('ui-widget-content');

    }else{
        jQuery(inputObj).removeClass('ui-state-highlight');
        jQuery(inputObj).addClass('ui-widget-content');
    }
}

deltaset.callbackOnError=function(data){

    //var strError=deltaset.callbackCommon(data,'OnError');
    //location.reload();
//alert(strError);

}

deltaset.callbackOnEvent=function(data){

    //var strEvent=deltaset.callbackCommon(data,'OnEvent');
    if('success'==data.status){
        deltaset.applyStyle();
    }
//alert(strEvent);
}

deltaset.callbackCommon=function(data,name){
    // alert('in callback..'+name+'\ndata.status='+data.status)
    if('complete'==data.status){
    // alert('data.responseXML='+data.responseXML+'\ndata.responseText='+data.responseText)
    }
    //the assumption about empty ViewState is wrong.
    //deltaset.checkForError(data.responseXML,name);

    var str='';
    //for (var i in data){
    //    str+='data.'+i+'='+eval('data.'+i)+'\n';
    //}
    //alert(name+' data :\n'+str);
    return name+' data :\n'+str;
}

deltaset.checkForError=function(responseXMLObj,name){
    //this method is needed because of strange behaviour in Chrome, IE, Safari and Opera
    //the only place where the error check on session timeout was working as expected was FF
    //after that 'fix' the script should be reliable in case of session timeout..
    if(null!=responseXMLObj){

        var partialResponse = responseXMLObj.getElementsByTagName('partial-response');
        if(0==partialResponse.length){
            //opera 10.x case...
            alert('no partialResponse.. possible error... called from:'+name+'\n refreshing page');
            location.reload();
        }

        var forUpdate=responseXMLObj.getElementsByTagName('update');
        //alert('forUpdate='+forUpdate.length);

        if(1==forUpdate.length){
            if('javax.faces.ViewState'==forUpdate[0].getAttribute('id')){
                alert('only javax.faces.ViewState is for update \npossible error... called from:'+name+'\n refreshing page');
                location.reload();
            }
        }
    }
}

deltaset.theme=function(){
    if(null==deltaset._themeInstance){
        deltaset._themeInstance=new deltaset._theme();
    }
    return deltaset._themeInstance;
}

deltaset._themeInstance=null;
deltaset._theme=function(){
    this.themeLinkId=null;
    this.inputId=null;
    this.fnDecorate=null;
    this.registered=false;
    this.registeredInputId=false;
    this.register=function(themeLinkId,fnDecorate){
        this.themeLinkId=themeLinkId;
        //fnDecorate = function(themeName){return '#{facesContext.externalContext.requestContextPath}#{facesContext.externalContext.requestServletPath}/javax.faces.resource/theme/'+themeName+'/jquery-ui-theme.css';}
        this.fnDecorate=fnDecorate;
        this.registered=true;
        return this;
    };
    this.registerInputId=function(inputId){
        this.inputId=inputId;
        this.registeredInputId=true;
        return this;
    };

    this.checkRegistered=function(){
        var error='';
        if(false==this.registered){
            error='   deltaset.theme().register(themeLinkId,fnDecorate) should be called!';
        }
        if(false==this.registered){
            error='   deltaset.theme().registerInputId(inputId) should be called!';
        }
        if(''!=error){
            alert('deltaset.theme() object not initialized properly.\n'+error);
        }
        return this.registered&&this.registeredInputId;
    }

    this.previewStyle=function(themeName){
        if(false==this.checkRegistered()) return;
        var activeStyleObj=document.getElementById(this.themeLinkId);
        activeStyleObj.disabled=true;        
        activeStyleObj.href=this.fnDecorate(themeName);
        activeStyleObj.disabled=false;
    };
    this.reset=function(){
        if(false==this.checkRegistered()) return;
        this.previewStyle(document.getElementById(this.inputId).value);        
    };
    this.changeTo=function(themeName){
        if(false==this.checkRegistered()) return;
        this.previewStyle(themeName);
        document.getElementById(this.inputId).value=themeName;
    };
};



deltaset.applyStyle=function(){
    jQuery('.ds-button').button();
};

//function injectViewData is needed because of http://java.net/jira/browse/JAVASERVERFACES-1718
//injectViewData should be registered with 
//jsf.ajax.addOnEvent(deltaset.injectViewData);
	
deltaset.injectViewData=function(data){
    if('success'!=data.status){
        return;
    }
    deltaset.injectViewDataDIRECT(data);
};
deltaset.injectViewDataDIRECT=function(data){    
    var viewDataValue = deltaset._extractViewState(data);      
    var partialResponse = data.responseXML.documentElement;				
    var viewUpdateArr = partialResponse.getElementsByTagName("update");      
    for(var k=0;k<viewUpdateArr.length;k++){
        var id = viewUpdateArr[k].getAttribute("id");
        var obj = document.getElementById(id);
        if(obj!=null){ 
            if(obj.tagName=="FORM"||obj.tagName=="form"){   
                //should be a single form and it is the 'obj' object'
                deltaset._addViewData(obj,viewDataValue);
            }else{
                var formArr = obj.getElementsByTagName("form");               
                for(var f=0;f<formArr.length;f++){
                    var formObj = formArr[f];
                    deltaset._addViewData(formObj,viewDataValue);
                }
            }
			    
        }
    }
};
	
deltaset._addViewData=function(formObj,viewDataValue){    
    var inputArr = formObj.getElementsByTagName("input");
    var hasViewData = false;
    for(var j=0;j<inputArr.length;j++){		     
        if("javax.faces.ViewState"==inputArr[j].getAttribute("name")){
            inputArr[j].value=viewDataValue;
            hasViewData=true;
        }
    }
    if(false==hasViewData){
        var inputViewData = document.createElement("input");
        inputViewData.setAttribute("name","javax.faces.ViewState");
        inputViewData.setAttribute("id","javax.faces.ViewState");
        inputViewData.setAttribute("type","hidden");
        inputViewData.setAttribute("value",viewDataValue);
        formObj.appendChild(inputViewData);
    }
};

//data.responseXml
deltaset._extractViewState =function(data){
    var partialResponse = data.responseXML.documentElement;				
    var viewState = partialResponse.getElementsByTagName("update");    
    for(var k=0;k<viewState.length;k++){
        if("javax.faces.ViewState"==viewState[k].getAttribute("id")){
            return viewState[k].firstChild.data;
        }		 
    }
    return "";//might be needed a different 'empty' string if nothing was found
};

